package com.rykj.energy.task.capture.util;

import com.rykj.energy.common.utils.StringUtils;
import com.rykj.energy.database.pojo.vo.PicturParamVo;
import com.rykj.energy.database.pojo.vo.RectSeatVo;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;


public class AlgorithmImageUtil {

    private static Logger logger = LoggerFactory.getLogger(AlgorithmImageUtil.class);

    /**
     * 将图片转换为算法sdk可用的byte[]
     *
     * @param picturParamVo
     * @param baos
     * @throws IOException
     */
    public static void setImageData(PicturParamVo picturParamVo, ByteArrayOutputStream baos) throws IOException {
        ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
        BufferedImage image = ImageIO.read(input);
        setImageData(picturParamVo, image);
    }

    /**
     * 将图片转换为算法sdk可用的byte[]
     *
     * @param faceParamVo
     * @param image
     * @throws IOException
     */
    public static void setImageData(PicturParamVo faceParamVo, BufferedImage image) throws IOException {
        faceParamVo.setWidth(image.getWidth());
        faceParamVo.setHeight(image.getHeight());
        byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();//关键
        faceParamVo.setImgData(pixels);
    }

    public static void setImageDataWithOpenCV(PicturParamVo picturParamVo, ByteArrayOutputStream baos) throws IOException {
        ByteArrayInputStream input = new ByteArrayInputStream(baos.toByteArray());
        BufferedImage image = ImageIO.read(input);
        setImageDataWithOpenCV(picturParamVo, image);
    }

    public static void setImageDataWithOpenCV(PicturParamVo picturParamVo, BufferedImage image) throws IOException {
        int width = image.getWidth();
        int height = image.getHeight();

        byte[] pixels = null;
        //传入了图片本地存储路径，使用opencv读取，解决png、jpg(JFIF 1.01标准)和传入的是旋转过的图片不能检测到人脸的问题
        if (StringUtils.isNotBlank(picturParamVo.getImgPath())) {
            Mat mat = Imgcodecs.imread(picturParamVo.getImgPath());
            int cols = mat.cols();
            int rows = mat.rows();
            //判断上传的图片是否被旋转过，旋转过的图片mat获取的宽高和BufferedImage的宽高相反
            if (width != height && width == rows && height == cols) {
                logger.info("上传的图片是被旋转过的, 原始width: {}, height: {}, 传入算法SDK中的width: {}, height: {}", width, height, cols, rows);
                width = cols;
                height = rows;
            }
            pixels = new byte[mat.channels() * cols * rows];
            mat.get(0, 0, pixels);
            mat.release();
        } else {
            //没有传入图片本地存储路径，使用opencv转换，解决png、jpg(JFIF 1.01标准)不能检测到人脸的问题
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(image, picturParamVo.getSuffix(), out);
            byte[] b = out.toByteArray();
            Mat mat = Imgcodecs.imdecode(new MatOfByte(b), Imgcodecs.CV_LOAD_IMAGE_COLOR);
            pixels = new byte[mat.channels() * mat.cols() * mat.rows()];
            mat.get(0, 0, pixels);
            mat.release();
        }

//		Mat mat1 = Imgcodecs.imread("D:\\3.jpg");
//		System.out.println(mat1.cols() + "  " + mat1.rows());
//        byte[] b = new byte[mat1.channels() * mat1.cols() * mat1.rows()];
//        mat1.get(0,0,b);
//        Mat data = new Mat(mat1.rows(), mat1.cols(), CvType.CV_8UC3);
//        data.put(0, 0, b);
//        Imgcodecs.imwrite("D:\\tt1.jpg", data);
//        
//        ByteArrayOutputStream out = new ByteArrayOutputStream();
//		boolean flag = ImageIO.write(image, "jpg", out);
//		byte[] b1 = out.toByteArray();
//		Mat m = Imgcodecs.imdecode(new MatOfByte(b1), Imgcodecs.CV_LOAD_IMAGE_COLOR);
//		
////		// Create a Matrix the same size of image
////	    Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC4);
////	    // Fill Matrix with image values
////	    mat.put(0, 0, b1);
//	    
//	    Imgcodecs.imwrite("D:\\tt2.jpg", m);
//	    
//	    byte[] bb = new byte[m.channels() * m.cols() * m.rows()];
//        m.get(0,0,bb);

        picturParamVo.setWidth(width);
        picturParamVo.setHeight(height);
        picturParamVo.setImgData(pixels);
    }

    /**
     * 原始图片根据坐标截图
     * @param rectSeatVo
     */
    public static void cutImgROI(RectSeatVo rectSeatVo) {
        try {
            //要剪切的图片的宽和高
           // int width = 140, height = 140;
            //要剪切的图片的起始坐标
           // int startX = 0, startY = 0;
            URL url =  new URL(rectSeatVo.getFileUrl());
            BufferedImage image = ImageIO.read(url);
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            ImageIO.write(image,rectSeatVo.getSuffix(), out);
            byte[] b = out.toByteArray();
            //源图片Mat
            Mat img = Imgcodecs.imdecode(new MatOfByte(b), Imgcodecs.CV_LOAD_IMAGE_COLOR);
            //Mat img = Imgcodecs.imread("img/Lena.jpg");
            //目标Mat
            Mat imgDesc = new Mat(rectSeatVo.getWidth(), rectSeatVo.getHeight(), CvType.CV_8UC3);
            //设置ROI
            Mat imgROI = new Mat(img, new Rect(rectSeatVo.getStartX(), rectSeatVo.getStartY(), rectSeatVo.getWidth(), rectSeatVo.getHeight()));
            //从ROI中剪切图片
            imgROI.copyTo(imgDesc);

            Imgcodecs.imwrite(rectSeatVo.getTargetFile(),imgDesc);
            img.release();
            imgDesc.release();
            imgROI.release();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}
